package com.dog.modules.iot.mqtt.codec;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.dog.modules.iot.mqtt.consumer.bound.InboundHeader;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.List;

/**
 */
@Component
@Slf4j
public class BodyDecoder {

    @Autowired
    private SecretService secretService;


    /**
     * 业务消息：
     * {
     *     "header":{
     *         "cmd":1113,
     *         "deviceCode": "xxx"
     *     },
     *     "data":{
     *         "version": "xxx"// 版本号
     *     }
     * }
     * 上线消息：
     * {
     * 	"username": "admin",
     * 	"ts": 1605769442169,
     * 	"sockport": 1883,
     * 	"proto_ver": 4,
     * 	"proto_name": "MQTT",
     * 	"keepalive": 20,
     * 	"ipaddress": "192.168.16.91",
     * 	"expiry_interval": 0,
     * 	"connected_at": 1605769442169,
     * 	"connack": 0,
     * 	"clientid": "robots-iot-dev_in_1605769506422",
     * 	"clean_start": true
     * }
     * 下线消息：
     * {
     * 	"username": "admin",
     * 	"ts": 1605769426233,
     * 	"reason": "tcp_closed",
     * 	"disconnected_at": 1605769426232,
     * 	"clientid": "robots-iot-dev_in_1605768269712"
     * }
     */


    /**
     * 业务消息：
     * 解析请求头
     *
     * @param msg
     * @return
     */
    public InboundHeader parseHeader(String msg) {
        InboundHeader inboundHeader = new InboundHeader();
        JSONObject jsonObject = JSONObject.parseObject(msg);
        JSONObject header = jsonObject.getJSONObject("header");
        if (header != null) {
            inboundHeader.setDeviceCode(header.getString("deviceCode"));
            inboundHeader.setCmd(header.getInteger("cmd"));
            inboundHeader.setTs(header.getLong("ts"));
            return inboundHeader;
        }
        return inboundHeader;
    }

    public String parseData(String body) {
        JSONObject jsonObject = JSONObject.parseObject(body);
        return jsonObject.getString("data");
    }

    public String decodeData(String deviceCode, Object body, boolean isEncode) {
        String decodeData = body.toString();
        if (!ObjectUtils.isEmpty(body) && isEncode) {
            byte[] decode = Base64.getDecoder().decode(decodeData.getBytes(StandardCharsets.UTF_8));
            SecretKey key = secretService.getSecretKey(deviceCode);
            if (key != null) {
                byte[] secret = key.getSecretKey().getBytes();
                byte[] iv = key.getIv().getBytes();
                byte[] bytes = AES.decode(decode, secret, iv);
                if (bytes != null) {
                    decodeData = new String(bytes);
                }
            }
        }
        return decodeData;
    }

    /**
     * 业务消息：
     * 解析普通对象参数
     *
     * @param deviceCode
     * @param encodeData
     * @param isEncode
     * @param type
     * @param <T>
     * @return
     */
    public <T> T decodeDataWithSimpleObject(String deviceCode, Object encodeData, boolean isEncode, Type type) {
        String dataStr = this.decodeData(deviceCode, encodeData, isEncode);
        return JSON.parseObject(dataStr, type);
    }

    /**
     * 解析list对象参数
     *
     * @param deviceCode
     * @param encodeData
     * @param isEncode
     * @param types
     * @return
     */
    public List<Object> decodeDataWithArray(String deviceCode, Object encodeData, boolean isEncode, Type[] types) {
        String dataStr = this.decodeData(deviceCode, encodeData, isEncode);
        return JSON.parseArray(dataStr, types);
    }

    /**
     * 上下线消息：
     * 解析clientid
     *
     * @param msg
     * @return
     */
    public String parseUuidFromClientId(String msg) {
        JSONObject jsonObject = JSONObject.parseObject(msg);
        return jsonObject.get("clientid").toString();
    }

}
